package gateway.mgt

import com.amihaiemil.camel.Yaml
import gateway.mgt.api.ApiDefinition
import gateway.mgt.api.ApiGroup
import gateway.mgt.runtime.GatewayCore
import grails.testing.mixin.integration.Integration
import grails.transaction.Rollback
import spock.lang.Specification

@Integration(applicationClass=mgtcore.Application)
@Rollback
class GatewayCoreIntegrationSpec extends Specification {

    static final ApiDefinitionPropertiesSet = [
            [
                    name   : "demo1", description: "demo api 1",
                    request: [path: "/Service-Set-1/sampleApi1"], backend: [uri: "lb://Service-Set-1", path: "/sampleApi1"]
            ],
            [
                    name   : "demo2", description: "demo api 2",
                    request: [path: "/Service-Set-2/sampleApi2"], backend: [uri: "lb://Service-Set-2", path: "/sampleApi2"]
            ]
    ]

    def setup() {
    }

    def cleanup() {
    }

    void "test method 'toYamlString()'"() {
        given:
        def instance = new GatewayCore()
        instance.addToApiGroups(name: "default1")
        instance.save(flush: true)

        ApiDefinitionPropertiesSet.each {
            it.apiGroup = ApiGroup.findByName("default1")
            new ApiDefinition(it).save(flush: true)
        }

        instance.refresh()

        when:
        def yaml = Yaml.createYamlInput(instance.toYamlString()).readYamlMapping()
        def routes = yaml.yamlMapping("spring").yamlMapping("cloud").yamlMapping("gateway").yamlSequence("routes")

        then:
        ApiDefinitionPropertiesSet.eachWithIndex { Map apidef, int rIdx ->
            def route = routes.yamlMapping(rIdx)

            assert route.string("id") == apidef.name
            assert route.string("uri") == apidef.backend.uri

            assert route.yamlSequence("predicates").string(0).endsWith("$apidef.request.path")
        }
    }

    void "test method 'publish()'"() {
        given:
        def instance = new GatewayCore()
        instance.addToApiGroups(name: "default1")
        instance.save(flush: true)

        ApiDefinitionPropertiesSet.each {
            it.apiGroup = ApiGroup.findByName("default1")
            new ApiDefinition(it).save(flush: true)
        }

        instance.refresh()

        when:
        def result = instance.publish()

        then:
        result.containsKey("commitId")
        result.containsKey("remoteUpdates")
        result.remoteUpdates.size() == 1
    }
}
